from fastapi import FastAPI
import asyncio
from typing import Callable
from database import redis,mysql
import redis.asyncio as aioredis
import json

from queues import Rabbitmq, Redis as MQ_Redis
from core.Config import settings
from server.admin.Task import TaskManager

def startup(app:FastAPI)-> Callable:
    """
    应用启动
    :param app:
    :return : 启动方法
    """
    async def app_start()-> None:
        # 创建数据库
        await mysql.create_db_and_tables()
        # 创建缓存
        app.state.cache = await redis.redis_cache()
        # 创建定时任务
        await TaskManager.start()
        # 创建配置
        await redis.update_config_to_redis(app)

        # 创建rabbitmq
        if settings.RABBITMQ_HOST is not None:
            await Rabbitmq.setup_rabbitmq()
        else:
            await MQ_Redis.create_log_queue()

        if settings.IS_CREATE_OPENAPI:
            with open("openapi.json", "w") as f:
                json.dump(app.openapi(), f, indent=2)

    return app_start

def stopping(app:FastAPI)-> Callable:
    """
    应用停止
    :param app:
    :return:停止钩子方法
    """
    async def stop_app()-> None:
        # 关闭缓存redis
        cache: aioredis.Redis = await app.state.cache
        await cache.close()
        # 关闭数据库
        mysql.engine.dispose()
        # TODO: 关闭rabbitmq
        await Rabbitmq.close_rabbitmq()
        await MQ_Redis.close_log_queue()
        # 关闭定时任务
        await TaskManager.shutdown()
    return stop_app